package com.credit.anypermission.permission

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.credit.anypermission.AnyPermission
import com.credit.anypermission.interfaces.IPermissionProcessor
import com.credit.anypermission.interfaces.RequestInterceptor
import com.credit.anypermission.interfaces.RequestListener
import java.util.*

abstract class PermissionBase : IPermissionProcessor {

    private var mAllNeededPermissions: List<String>? = null
    val mUnGrantedPermissions: Queue<String> = LinkedList()
    private var mListener: RequestListener? = null
    private lateinit var mContext: Context

    override fun setActivity(activity: FragmentActivity) {
        mContext = activity
    }

    override fun setFragment(fragment: Fragment) {
        mContext = fragment.requireContext()
    }

    override fun permissions(vararg permissions: String) {
        this.mAllNeededPermissions = permissions.asList()
        for (permission in mAllNeededPermissions!!) {
            if (AnyPermission.hasPermissions(mContext, permission)) {
                mUnGrantedPermissions.remove(permission)
            } else {
                if (!mUnGrantedPermissions.contains(permission)) {
                    mUnGrantedPermissions.offer(permission)
                }
            }
        }
    }

    private var mOnBeforeRequest: RequestInterceptor<String>? = null
    private var mOnBeenDenied: RequestInterceptor<String>? = null
    private var mOnGoSetting: RequestInterceptor<String>? = null

    override fun onBeforeRequest(onBeforeRequest: RequestInterceptor<String>) {
        this.mOnBeforeRequest = onBeforeRequest
    }

    override fun onBeenDenied(onBeenDenied: RequestInterceptor<String>) {
        this.mOnBeenDenied = onBeenDenied
    }

    override fun onGoSetting(onGoSetting: RequestInterceptor<String>) {
        this.mOnGoSetting = onGoSetting
    }

    override fun requestListener(listener: RequestListener) {
        this.mListener = listener
        next()
    }

    private fun onBeforeRequest() {
        if (mOnBeforeRequest == null) {
            request()
            return
        }
        mOnBeforeRequest!!.intercept(
            PermissionNameConvert.getPermissionString(
                mContext,
                mUnGrantedPermissions.peek()
            ),
            object : RequestInterceptor.Executor {
                override fun execute() {
                    request()
                }

                override fun cancel() {
                    onFailed()
                }
            })
    }

    private fun onBeenDenied() {
        if (mOnBeenDenied == null) {
            request()
            return
        }
        mOnBeenDenied!!.intercept(PermissionNameConvert.getPermissionString(mContext, mUnGrantedPermissions.peek()),
            object : RequestInterceptor.Executor {
                override fun execute() {
                    request()
                }

                override fun cancel() {
                    onFailed()
                }
            })
    }

    private fun onGoSetting() {
        if (mOnGoSetting == null) {
            setting()
            return
        }
        mOnGoSetting!!.intercept(PermissionNameConvert.getPermissionString(mContext, mUnGrantedPermissions.peek()),
            object : RequestInterceptor.Executor {
                override fun execute() {
                    setting()
                }

                override fun cancel() {
                    onFailed()
                }
            })
    }

    operator fun next() {
        if (mUnGrantedPermissions.peek() == null) {
            onSuccess()
            return
        }
        if (AnyPermission.hasPermissions(mContext, mUnGrantedPermissions.peek()!!)) {
            mUnGrantedPermissions.poll()
            next()
            return
        }
        onBeforeRequest()
    }

    fun again() {
        if (mUnGrantedPermissions.peek() == null) {
            onSuccess()
            return
        }
        if (AnyPermission.hasPermissions(mContext, mUnGrantedPermissions.peek()!!)) {
            mUnGrantedPermissions.poll()
            next()
            return
        }
        if (AnyPermission.isPermissionPermanentDenied(mContext, mUnGrantedPermissions.peek())) {
            onGoSetting()
        } else {
            onBeenDenied()
        }
    }

    private fun setting() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.data = Uri.fromParts("package", mContext.packageName, null)
        mContext.startActivity(intent)
    }

    fun onSuccess() {
        mListener?.onSuccess()
    }

    fun onFailed() {
        mListener?.onFailed()
    }

    abstract fun request()

}